package com.asiainfo.iam.service.impl;

import com.alibaba.fastjson.JSON;
import com.asiainfo.iam.constant.MQConstant;
import com.asiainfo.iam.entity.po.ModoTeam;
import com.asiainfo.iam.entity.po.ModoTeamMember;
import com.asiainfo.iam.entity.po.ModoTeamMemberRole;
import com.asiainfo.iam.entity.po.ModoUser;
import com.asiainfo.iam.entity.vo.MessageBase;
import com.asiainfo.iam.entity.vo.Organization;
import com.asiainfo.iam.entity.vo.Role;
import com.asiainfo.iam.entity.vo.User;
import com.asiainfo.iam.mapper.ModoTeamMapper;
import com.asiainfo.iam.mapper.ModoTeamMemberMapper;
import com.asiainfo.iam.mapper.ModoTeamMemberRoleMapper;
import com.asiainfo.iam.mapper.ModoUserMapper;
import com.asiainfo.iam.service.MessageServiceTest;
import com.asiainfo.iam.tool.ToPo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static dm.jdbc.desc.Configuration.user;

@Service
public class MessageServiceTestImpl implements MessageServiceTest {
    private static final Logger log = LoggerFactory.getLogger(MessageServiceTestImpl.class);
    @Autowired
    private ModoTeamMapper modoTeamMapper;

    @Autowired
    private ModoUserMapper modoUserMapper;

    @Autowired
    private ModoTeamMemberRoleMapper modoTeamMemberRoleMapper;

    @Autowired
    private ModoTeamMemberMapper modoTeamMemberMapper;

    @Autowired
    private ToPo toPo;
    @Override
    public void handleFullData(String objectType, MessageBase message) {
        log.info("处理全量数据: {}", objectType);
        //存储三者
        Map<String, String> memberData = new HashMap<>();
        switch (objectType) {
            case MQConstant.OBJECT_ORG:
                Organization org = JSON.parseObject(
                        JSON.toJSONString(message.getMsgData()),
                        Organization.class
                );
                handleOrgAdd(org);
                break;

            case MQConstant.OBJECT_ROLE:
                Role role = JSON.parseObject(
                        JSON.toJSONString(message.getMsgData()),
                        Role.class
                );
                handleRoleAdd(role);
                memberData.put("roleName", role.getRoleName());
                break;

            case MQConstant.OBJECT_USER:
                User user = JSON.parseObject(
                        JSON.toJSONString(message.getMsgData()),
                        User.class
                );
                handleUserAdd(user);
                memberData.put("userId", user.getAccount());
                memberData.put("teamName", user.getOrgName());
                break;

            default:
                log.warn("未知对象类型: {}", objectType);
        }
        //更新三者之间关系表
        handleMemberAdd(memberData.get("teamName"),
                memberData.get("userId"),
                memberData.get("roleName"));
    }


    @Override
    public void handleIncrementalData(String objectType, String operateType, MessageBase message) {
        log.info("处理增量数据: {}, 操作类型: {}", objectType, operateType);

        // 1. 新增操作：按 组织→角色→用户 顺序处理（确保依赖对象先存在）
        if (MQConstant.OPERATE_ADD.equals(operateType)) {
            //存储三者
            Map<String, String> memberData = new HashMap<>();
            // 强制按组织→角色→用户的顺序处理，即使消息顺序错乱也按此规则执行
            switch (objectType) {
                case MQConstant.OBJECT_ORG:
                    Organization org = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            Organization.class
                    );
                    handleOrgAdd(org);  // 先处理组织新增
                    break;
                case MQConstant.OBJECT_ROLE:
                    Role role = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            Role.class
                    );
                    handleRoleAdd(role);  // 再处理角色新增
                    memberData.put("roleName", role.getRoleName());
                    break;
                case MQConstant.OBJECT_USER:
                    User user = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            User.class
                    );
                    handleUserAdd(user);  // 最后处理用户新增
                    memberData.put("userId", user.getAccount());
                    memberData.put("teamName", user.getOrgName());
                    break;
                default:
                    log.warn("未知新增对象类型: {}", objectType);
            }
            //更新三者之间关系表
            handleMemberAdd(memberData.get("teamName"),
                    memberData.get("userId"),
                    memberData.get("roleName"));

        }
        //2.处理更新操作
        else if (MQConstant.OPERATE_UPDATE.equals(operateType)) {
            //存储三者
            Map<String, String> memberDataUpdate = new HashMap<>();
            switch (objectType) {
                case MQConstant.OBJECT_USER:
                    User user = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            User.class
                    );
                    handleUserUpdate(user);
                    memberDataUpdate.put("userId", user.getAccount());
                    memberDataUpdate.put("teamName", user.getOrgName());
                    break;
                case MQConstant.OBJECT_ROLE:
                    Role role = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            Role.class
                    );
                    handleRoleUpdate(role);
                    memberDataUpdate.put("roleName", role.getRoleName());
                    break;
                case MQConstant.OBJECT_ORG:
                    Organization org = JSON.parseObject(
                            JSON.toJSONString(message.getMsgData()),
                            Organization.class
                    );
                    handleOrgUpdate(org);
                    break;
                default:
                     log.warn("未知修改对象类型: {}", objectType);
            }
            handleMemberUpdate(memberDataUpdate.get("teamName"),
                    memberDataUpdate.get("userId"),
                    memberDataUpdate.get("roleName"));

        }
        // 3. 处理删除操作：按 用户→角色→组织 顺序处理（避免依赖冲突）
        else if ( MQConstant.OPERATE_DELETE.equals(operateType)) {
            // 强制按用户→角色→组织的顺序处理
            switch (objectType) {
                case MQConstant.OBJECT_USER:
                    handleUserDelete(message);
                    break;
                case MQConstant.OBJECT_ROLE:
                    handleRoleDelete(message);
                    break;
                case MQConstant.OBJECT_ORG:
                    handleOrgDelete(message);  // 组织删除需特殊处理（先删用户）
                    break;
                default:
                    log.warn("未知修改/删除对象类型: {}", objectType);
            }
        } else {
            log.warn("不支持的操作类型: {}", operateType);
        }
    }




    /**
     *全量--组织
     */
    private void handleOrgAdd(Organization org) {
        log.info("同步新增团队: {}", org.getId());

        try {
            ModoTeam existing = modoTeamMapper.findById(org.getId());
            ModoTeam modoTeam = toPo.toModoTeam(org);

            if (existing == null) {
                modoTeamMapper.insert(modoTeam);
                log.info("团队新增成功!");
            }else {
                log.info("团队已存在！ ");
            }
        } catch (Exception e) {
            log.error("团队同步失败: {}", e);
            throw new RuntimeException("团队同步失败", e);
        }
    }

    /**
     *全量--用户
     */
    private void handleUserAdd(User user) {
        log.info("同步新增用户: {}", user.getAccount());
        try {
            ModoUser existing = modoUserMapper.findById(user.getAccount());
            ModoUser modoUser = toPo.toModoUser(user);

            if (existing == null) {
                modoUserMapper.insert(modoUser);
                log.info("用户新增成功!");
            }else {
                log.info("用户已存在！");
            }
        } catch (Exception e) {
            log.error("用户同步失败: {}", e);
            throw new RuntimeException("用户同步失败", e);
        }
    }

    /**
     *全量--角色
     */
    private void handleRoleAdd(Role role) {
        log.info("同步新增角色: {}", role.getRoleName());
        try {
            ModoTeamMemberRole existing = modoTeamMemberRoleMapper.findByName(role.getRoleName());
            ModoTeamMemberRole modoTeamMemberRole = toPo.toModoTeamMemberRole(role);

            if (existing == null) {
                modoTeamMemberRoleMapper.insert(modoTeamMemberRole);
                log.info("角色新增成功！ ");
            }else {
                log.info("角色已存在！ ");
            }
        } catch (Exception e) {
            log.error("角色同步失败: {}", e);
            throw new RuntimeException("角色同步失败", e);
        }

    }

    /**
     * 全量三者关系表
     */
    private void handleMemberAdd(String teamName,String userId,String roleName) {
        log.info("新增关系表");
        try {
            if (userId!=null){
                ModoTeamMember existing = modoTeamMemberMapper.findById(userId);
                ModoTeamMember modoTeamMember = toPo.toModoTeamMember(teamName, userId, roleName);
                if (existing == null) {
                    modoTeamMemberMapper.insert(modoTeamMember);
                    log.info("关系表新增成功！ ");
                }else {
                    log.info("关系表已存在！ ");
                }
            }

        } catch (Exception e) {
            log.error("表关系同步失败: {}", e);
            throw new RuntimeException("表关系同步失败", e);
        }

    }

    /**
     * 增量--更新用户
     */
    private void handleUserUpdate(User user) {
        log.info("开始更新用户: {}", user.getAccount());
        try {
            ModoUser existingUser = modoUserMapper.findById(user.getAccount());
            ModoUser modoUser = toPo.toModoUser(user);
            if (existingUser != null) {
                modoUserMapper.update(modoUser);
                log.info("用户更新成功！ ");
            }else {
                log.info("用户不存在！ ");
            }
        }
        catch (Exception e) {
            log.error("用户更新失败: {}", e);
            throw new RuntimeException("用户更新失败", e);
        }
    }

    /**
     * 增量--更新角色
     */
    private void handleRoleUpdate(Role role) {
        log.info("开始更新角色: {}", role.getRoleName());
        try {
            ModoTeamMemberRole existingRole = modoTeamMemberRoleMapper.findByName(role.getRoleName());
            ModoTeamMemberRole modoTeamMemberRole = toPo.toModoTeamMemberRole(role);
            if (existingRole != null) {
                modoTeamMemberRoleMapper.update(modoTeamMemberRole);
                log.info("角色更新成功！ ");
            }else {
                log.info("角色不存在！ ");
            }
        } catch (Exception e) {
            log.error("角色更新失败: {}", e);
            throw new RuntimeException("角色更新失败", e);
        }
    }

    /**
     * 增量--更新组织
     */
    private void handleOrgUpdate(Organization org) {
        log.info("开始更新团队: {}", org.getId());
        try {
            ModoTeam existing = modoTeamMapper.findById(org.getId());
            ModoTeam modoTeam = toPo.toModoTeam(org);
            if (existing != null) {
                modoTeamMapper.update(modoTeam);
                log.info("团队更新成功！ ");
            }else {
                log.info("团队不存在！ ");
            }
        }
        catch (Exception e) {
            log.error("团队更新失败: {}", e);
            throw new RuntimeException("团队更新失败", e);
        }
    }

    /**
     *增量--更新关系表
     */
    private void handleMemberUpdate(String teamName,String userId,String roleName) {
        log.info("开始更新关系表");
        try {
            if(userId!=null){
                ModoTeamMember existing = modoTeamMemberMapper.findById(userId);
                ModoTeamMember modoTeamMember = toPo.toModoTeamMember(teamName, userId, roleName);
                if (existing != null) {
                    modoTeamMemberMapper.update(modoTeamMember);
                    log.info("关系表更新成功！ ");
                }
            }

        }
        catch (Exception e) {
            log.error("关系表更新失败: {}", e);
            throw new RuntimeException("关系表更新失败", e);
        }
    }

    /**
     * 增量--删除用户
     */
    private void handleUserDelete(MessageBase message) {
        User user = JSON.parseObject(
                JSON.toJSONString(message.getMsgData()),
                User.class
        );
        log.info("开始删除用户: {}", user.getId());
        try {
            ModoUser existingUser = modoUserMapper.findById(user.getAccount());
            ModoTeamMember existingMember = modoTeamMemberMapper.findById(user.getAccount());
            if (existingUser != null) {
                modoUserMapper.deleteById(user.getAccount());
                log.info("用户删除成功！");
                if(existingMember != null){
                    modoTeamMemberMapper.deleteById(user.getAccount());
                    log.info("移除用户表关系！");
                }
            }else {
                log.info("用户不存在！");
            }
        } catch (Exception e) {
            log.error("用户删除失败: {}", e);
            throw new RuntimeException("用户删除失败", e);
        }
    }
    /**
     * 增量--删除角色
     */
    private void handleRoleDelete(MessageBase message) {
        Role role = JSON.parseObject(
                JSON.toJSONString(message.getMsgData()),
                Role.class
        );
        log.info("开始删除角色: {}", role.getRoleName());
        try {
            ModoTeamMemberRole existing = modoTeamMemberRoleMapper.findByName(role.getRoleName());
            if (existing != null) {
                modoTeamMemberRoleMapper.deleteByName(role.getRoleName());
                log.info("角色删除成功！");
            }
        }
        catch (Exception e) {
            log.error("角色删除失败: {}", e);
            throw new RuntimeException("角色删除失败", e);
        }
    }

    /**
     * 增量--删除组织
     * 处理组织删除：先检查该组织下是否有用户，有则先删用户，再删组织
     */
    private void handleOrgDelete(MessageBase message) {
        Organization org = JSON.parseObject(
                JSON.toJSONString(message.getMsgData()),
                Organization.class
        );
        String teamName = org.getOrgName();
        String orgId = org.getId();
        log.info("开始处理团队删除，团队名字: {}", teamName);

        try {
            // 步骤1：查询该组织下的所有用户
            List<ModoTeamMember> allUser = modoTeamMemberMapper.findAllUser(teamName);  // 需在ModoUserMapper中新增此方法
            log.info("查询到团队[{}]下有{}个用户", teamName, allUser.size());

            // 步骤2：若有用户，先删除这些用户
            if (!allUser.isEmpty()) {
                for (ModoTeamMember member : allUser) {
                    //1.先删用户表的用户
                    modoUserMapper.deleteById(member.getUserId());  // 删除单个用户
                    //2.再删关系表的绑定关系
                    modoTeamMemberMapper.deleteById(member.getUserId());
                    log.info("已删除团队[{}]下的用户，用户ID: {}", teamName, member.getUserId());
                }
            }

            // 步骤3：删除组织
            ModoTeam existingOrg = modoTeamMapper.findById(orgId);
            if (existingOrg != null) {
                modoTeamMapper.deleteById(orgId);
                log.info("团队[{}]删除成功", orgId);
            } else {
                log.warn("团队[{}]不存在，无需删除", orgId);
            }

        } catch (Exception e) {
            log.error("团队[{}]删除失败", orgId, e);
            throw new RuntimeException("团队删除失败（含用户联动处理）", e);  // 事务回滚
        }
    }

}
